package Screens 
{
	import DeviceData.LocalDB;
	import ExternalService.ApiConnection;
	import feathers.controls.ButtonGroup;
	import feathers.controls.Label;
	import feathers.controls.Screen;
	import feathers.controls.TextInput;
	import feathers.data.ListCollection;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import Media.ExtendedMetalWorksMobileTheme;
	import starling.events.Event;
	/**
	 * ...
	 * @author Simon Claeye
	 */
	public class LogInScreen extends Screen
	{
		private var userNameIn:TextInput;
		private var passwordIn:TextInput;
		private var stateLabel:Label;
		private var database:LocalDB;
		
		public function LogInScreen(database:LocalDB) 
		{
			this.database = database;
			this.addEventListener( Event.ADDED_TO_STAGE, addedToStageHandler );
		}
		
		private function addedToStageHandler(event:Event):void
		{	
			trace("log in screen invoked");
			// handles the back and menu hardware keys on android
			this.backButtonHandler = backHandler;
			this.menuButtonHandler = menuHandler;
			
			stateLabel = new Label();
			stateLabel.x = (this.stage.stageWidth / 12);
			stateLabel.y = (this.stage.stageHeight / 12);
			stateLabel.visible = false;
			addChild(stateLabel);
			
			//Username
			var userNameLabel:Label = new Label();
			userNameLabel.text = "Username:";
			userNameLabel.nameList.add(ExtendedMetalWorksMobileTheme.INPUT_LABEL);
			userNameLabel.x = (this.stage.stageWidth / 12);
			userNameLabel.y = 3*(this.stage.stageHeight / 12);
			addChild(userNameLabel);
			
			this.userNameIn = new TextInput();
			this.userNameIn.setSize(10*(this.stage.stageWidth / 12), (this.stage.stageHeight / 12));
			this.userNameIn.x = (this.stage.stageWidth / 12);
			this.userNameIn.y = 4*(this.stage.stageHeight / 12);
			addChild(userNameIn);
			
			//Password
			var passwordLabel:Label = new Label();
			passwordLabel.text = "Password:";
			passwordLabel.nameList.add(ExtendedMetalWorksMobileTheme.INPUT_LABEL);
			passwordLabel.x = (this.stage.stageWidth / 12);
			passwordLabel.y = 5* (this.stage.stageHeight / 12);
			addChild(passwordLabel);
			
			this.passwordIn = new TextInput();
			passwordIn.setSize(10 * (this.stage.stageWidth / 12), (this.stage.stageHeight / 12));
			passwordIn.x = (this.stage.stageWidth / 12);
			passwordIn.y = 6 * (this.stage.stageHeight / 12);
			addChild(passwordIn);
			
			var group:ButtonGroup = new ButtonGroup();
			group.dataProvider = new ListCollection(
			[
				{ label: "Log In", triggered: logInHandler },
				{ label: "Cancel", triggered: cancelHandler },
			]);
			group.direction = ButtonGroup.DIRECTION_HORIZONTAL;
			group.gap = 5;
			group.x = (this.stage.stageWidth / 12);
			group.y = 8 * (this.stage.stageHeight / 12);
			
			addChild(group);
		}
		
		/**
		 * A function to dispatch an event when the back hardware key
		 * is pressed on android.
		 */
		private function backHandler():void
		{
			trace("back pressed");
			dispatchEvent(new NavigationEvent(NavigationEvent.RETURN));
		}
		
		/**
		 * A function to dispatch an event when the menu hardware key
		 * is pressed.
		 */
		private function menuHandler():void
		{
			trace("back pressed");
			dispatchEvent(new NavigationEvent(NavigationEvent.MAIN_MENU));
		}
		
		/**
		 * Function to handle the authenitcation with the website.
		 * @param	event
		 */
		private function logInHandler(event:Event):void
		{
			if (userNameIn.text != "" && passwordIn.text != "")
			{
				stateLabel.text = "Logging in...";
				stateLabel.visible = true;
				
				var connection:ApiConnection = new ApiConnection();
				connection.getAuthenticationToken(userNameIn.text, passwordIn.text,
					completeHandler, statusHandler, securityHandler, IOErrorHandler);
			}
			else
			{
				stateLabel.visible = true;
				//errorLabel.text = "You must enter a username\nand password.";
				stateLabel.text = "The Username/Password\ncombination was incorrect.";
			}
		}
		
		private function cancelHandler(event:Event):void
		{
			dispatchEvent(new NavigationEvent(NavigationEvent.RETURN));
		}
		
		/**
		 * Callback function to add the retrieved authentication token to the local database.
		 * @param	event
		 */
		private function completeHandler(event:Object):void
		{
			stateLabel.visible = false;
			var rawJSON:String = String(event.target.data);
			var array:Object = JSON.parse(rawJSON)
			
			database.deleteTokens();
			database.addToken(array["token"]);
			dispatchEvent(new NavigationEvent(NavigationEvent.CONTINUE));
		}
		
		/**
		 * Callback function to display an error message in case the server returns an
		 * HTTP status instead of json.
		 * @param	event
		 */
		private function statusHandler(event:HTTPStatusEvent):void
		{
			stateLabel.text = "The Username/Password\ncombination was incorrect.";
			stateLabel.visible = true;
		}
		
		private function securityHandler(event:SecurityErrorEvent):void
		{
			stateLabel.text = "A security error has occured,\n please try again.";
			stateLabel.visible = true;
		}
		
		private function IOErrorHandler(event:IOErrorEvent):void
		{
			stateLabel.text = "The server could not be contacted,\n please try again.";
			stateLabel.visible = true;
		}
	}
}